package lightControl;

import org.objectweb.proactive.ActiveObjectCreationException;
import org.objectweb.proactive.Body;
import org.objectweb.proactive.ProActive;
import org.objectweb.proactive.Service;
import org.objectweb.proactive.core.config.ProActiveConfiguration;
import org.objectweb.proactive.core.node.NodeException;
import org.objectweb.proactive.core.node.NodeFactory;
import org.objectweb.proactive.ext.migration.Destination;
import org.objectweb.proactive.ext.migration.MigrationStrategyImpl;

import event.Event;
import Bloques.*;
import event.*;
import principal.AgentMessageReceiver;
import principal.StreetControllerAgent;
import principal.agentFrame;

public class LightControlAgent implements org.objectweb.proactive.RunActive,
        java.io.Serializable {

    private boolean onItinerary = false;
    private boolean initialized;
    private transient agentFrame myFrame;
    private AgentMessageReceiver controler;
    private LightControlAgent otherLightControlAgent;
    private javax.swing.ImageIcon face;
    private org.objectweb.proactive.ext.migration.MigrationStrategy myStrategy;
    private org.objectweb.proactive.ext.migration.MigrationStrategyManager myStrategyManager;
    private int index;
    private String name;
    private String[] itinerary;
    int VERDE = 1;
    int ROJO = 0;
    int AMBAR = 3;
    int SE = 1; //Stop Event
    int CE = 2;//Cross Event
    int LCE = 3; //Light Change Event
    int CLE = 5; //Change Lane Event
    int CLEE = 6; //Change Lane End Event
    int ALE = 7; //Arrival Link Event
    int LLE = 8; //Leave Link Event
    int BE = 9; //Begin Event
    int AE = 10; //Arrival Event
    int WSE = 11; //Warning Event, as a stop event, but dont stop
    int WBE = 12; // warning Event, as a begin event, but actually for a dont stop event
    private StreetControllerAgent streetControllerAgent;
    private int n;
    private double t;

    public LightControlAgent() {
    }

    public LightControlAgent(Integer ind) {
        this.index = ind.intValue();
        this.name = "LigtControl Agent" + index;

    }

    public void loop() {
        rebuild();
    }

    public void rebuild() {
        Body body = ProActive.getBodyOnThis();
        myFrame = new agentFrame(face, body.getNodeURL(), index);

        sendMessageToControler("I just got in node " +
                ProActive.getBodyOnThis().getNodeURL());
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
        }
    }

    public void clean() {
        if (myFrame != null) {
            myFrame.dispose();
            myFrame = null;
        }
    }

    public String toString() {
        return this.name;
    }

    public void initialize(String[] s) {
        try {
            //With this we can load the image from the same location than
            //the classes
            ClassLoader cl = this.getClass().getClassLoader();
            //java.net.URL u = cl.getResource(
            //      "org/objectweb/proactive/examples/penguin/PenguinSmall.jpg");
            java.net.URL u = cl.getResource("Resources/scat.jpg");
            face = new javax.swing.ImageIcon(u);
        } catch (Exception e) {
            e.printStackTrace();
        }
        myStrategyManager = new org.objectweb.proactive.ext.migration.MigrationStrategyManagerImpl((org.objectweb.proactive.core.body.migration.Migratable) org.objectweb.proactive.ProActive.getBodyOnThis());
        myStrategyManager.onDeparture("clean");
        myStrategy = new MigrationStrategyImpl();
        itinerary = s;
        for (int i = 0; i < s.length; i++) {
            myStrategy.add(s[i], null);
        }
    }

    public void setControler(AgentMessageReceiver c) {
        this.controler = c;
        this.initialized = true;
    }

    public void setOther(LightControlAgent carGenerator) {
        this.otherLightControlAgent = carGenerator;
    }

    public Destination nextHop() {
        Destination r = myStrategy.next();
        if (r == null) {
            myStrategy.reset();
            r = myStrategy.next();
        }
        return r;
    }

    public void runActivity(Body b) {
        Service service = new Service(b);
        if (!initialized) {
            service.blockingServeOldest();
        }
        rebuild();
        Destination r = null;

        //ponerEvento(segmento,tiempo,tipo,objeto,posicion,desiredStatus,lane)

        double t;

        double f1 = 70;
        double f2 = 30;
        double f = f1 + f2;

        double frs1 = f1;
        double fas1;
        double fvs1 = fas1 = f2 / 2;
        double fvs2;
        double fas2 = fvs2 = frs1 / 2;
        double frs2 = f2;

        t = 1;
        while (b.isActive()) {
            while (service.hasRequestToServe()) {
                service.serveOldest();
            }

            if (onItinerary) {

                streetControllerAgent.ponerEvento(0, t, LCE, "S1", 132.0, ROJO, 0);
                streetControllerAgent.ponerEvento(35, t, LCE, "S2", 132.0, VERDE, 0);

                t = t + fas2;

                streetControllerAgent.ponerEvento(35, t, LCE, "S2", 132.0, AMBAR, 0);

                t = t + fvs2;
                streetControllerAgent.ponerEvento(0, t, LCE, "S1", 132.0, VERDE, 0);
                streetControllerAgent.ponerEvento(35, t, LCE, "S2", 132.0, ROJO, 0);

                t = t + fvs1;
                streetControllerAgent.ponerEvento(0, t, LCE, "S1", 132.0, AMBAR, 0);
                t = t + fas1;

                if (t < 600) {
                    f1 = 70;
                    f2 = 30;
                    f = f1 + f2;

                    frs1 = f1;

                    fvs1 = fas1 = f2 / 2;

                    fas2 = fvs2 = frs1 / 2;
                    frs2 = f2;
                }

                if (t >= 600 && t < 1200) {
                    f1 = 30;
                    f2 = 70;
                    f = f1 + f2;

                    frs1 = f1;

                    fvs1 = fas1 = f2 / 2;

                    fas2 = fvs2 = frs1 / 2;
                    frs2 = f2;

                }
                if (t >= 1200 && t < 1400) {
                    f1 = 50;
                    f2 = 50;
                    f = f1 + f2;

                    frs1 = f1;

                    fvs1 = fas1 = f2 / 2;

                    fas2 = fvs2 = frs1 / 2;
                    frs2 = f2;
                }
                if (t >= 1400) {
                    onItinerary = false;
                    sendMessageToControler("1");
                }


            /*try {
            Thread.sleep(1000);
            } catch (InterruptedException e) {
            }      */
//streetControllerAgent.ponerEvento(1,56,LCE,"S",0,VERDE,0);
            //streetControllerAgent.ponerEvento(1,61,LCE,"S",0,AMBAR,0);

//this.onItinerary = false;



            } else {
            // service.blockingServeOldest();
            }
        }
    }

    public String[] getItinerary() {
        return itinerary;
    }

    public void setItinerary(String[] newItinerary) {
        sendMessageToControler("I changed my itinerary", java.awt.Color.blue);
        myStrategy = new MigrationStrategyImpl();
        itinerary = newItinerary;
        for (int i = 0; i < newItinerary.length; i++) {
            myStrategy.add(newItinerary[i], null);
        }
    }

    public void start(StreetControllerAgent streetControllerAgent) {
        sendMessageToControler("I am starting my itinerary",
                new java.awt.Color(0, 150, 0));
        myStrategy.reset();
        onItinerary = true;
        System.out.println("init lightcontroler");
        this.streetControllerAgent = streetControllerAgent;
    }

    public void listo() {
        onItinerary = true;
        System.out.println("listo");
    }

    public void suspend() {
        if (!onItinerary) {
            sendMessageToControler("I'm already suspended");
        } else {
            sendMessageToControler("I suspended my itinerary",
                    java.awt.Color.red);
            onItinerary = false;
        }
    }

    public void resume() {
        if (onItinerary) {
            sendMessageToControler("I'm already on my itinerary");
        } else {
            sendMessageToControler("I'm resuming my itinerary",
                    new java.awt.Color(0, 150, 0));
            onItinerary = true;
        }
    }

    public String call() {
        return "[" + name + "] : I am working on node " +
                ProActive.getBodyOnThis().getNodeURL();
    }

    public void chainedCall() {
        if (otherLightControlAgent != null) {
            sendMessageToControler("I'm calling my peer agent");
            otherLightControlAgent.chainedCall();
        } else {
            sendMessageToControler("I don't have a peer agent to call");
        }
    }

    private void sendMessageToControler(String message) {
        if (controler != null) {
            controler.receiveMessage(message);
        }
    }

    private void sendMessageToControler(String message, java.awt.Color color) {
        if (controler != null) {
            controler.receiveMessage("[" + name + "] : " + message, color);
        }
    }
}


